﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;

namespace TestNugetWrapper
{
    public class ProjectAdapter : IDisposable
    {
        #region Public Properties

        public XDocument CurrentProject { get; set; }
        public XNamespace Xns { get; set; }

        #endregion

        #region Private Properties

        private string CurrentProjectUri { get; set; }

        #endregion

        #region Constructors

        public ProjectAdapter(string projectUri)
        {
            this.CurrentProjectUri = projectUri;
            this.CurrentProject = XDocument.Load(this.CurrentProjectUri);
            this.Xns = this.CurrentProject.Root.Name.Namespace;
        }

        #endregion

        #region Finalizer

        ~ProjectAdapter()
        {
            this.Dispose(false);
        }

        #endregion

        #region Public Methods

        internal void AddReference(AssemblyReference reference)
        {
            var projectNode = this.CurrentProject.Root;

            var referencesItemGroupNode = projectNode.Elements(this.Xns + "ItemGroup")
                .Where(t => t.Element(this.Xns + "Reference") != null)
                .FirstOrDefault();

            var referenceNodes = this.CurrentProject.Root
                .Descendants()
                .Elements(this.Xns + "Reference");

            var referenceNode = referenceNodes
                .Where(t => t.Attribute("Include").Value == reference.AssemblyName)
                .FirstOrDefault();

            if (referenceNode == null)
            {
                var newReferenceNode = new XElement(this.Xns + "Reference");
                newReferenceNode.Add(new XAttribute("Include", reference.AssemblyName));
                var hintPathNode = new XElement(this.Xns + "HintPath");
                hintPathNode.Value = reference.HintPath;
                newReferenceNode.Add(hintPathNode);

                //create new node
                referencesItemGroupNode.Add(newReferenceNode);
            }
            else
            {
                var hintPathNode = referenceNode.Element(this.Xns + "HintPath");
                hintPathNode.Value = reference.HintPath;
            }
        }

        #endregion

        #region Protected Virtual Members

        protected virtual void Dispose(bool isDisposing)
        {
            if (!string.IsNullOrWhiteSpace(this.CurrentProjectUri))
            {
                this.CurrentProject.Save(this.CurrentProjectUri);
            }

            if (isDisposing)
                GC.SuppressFinalize(this);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            this.Dispose(true);
        }

        #endregion
    }
}
